#include "../spicy.h"

#include "vcd-logined-window.h"
#include "vcd-start-window.h"
#include "vcd-setting-window/setting-network/vcd-node.h"

#include "../vcd-common-api/vcd-css.h"
#include "../vcd-common-api/vcd-download.h"
#include "../vcd-common-api/vcd-json-parser.h"
#include "../vcd-common-api/vcd-common.h"
#include "../vcd-common-api/vcd-get-vm-info.h"
#include "../vcd-common-api/vcd-vm-connect.h"
#include "../vcd-common-api/vcd-vm-rdp-connect.h"
#include "../vcd-common-api/vcd-get-login-ticket.h"
#include "../vcd-common-api/vcd-refresh-vm-info.h"
#include "../vcd-common-api/vcd-log.h"
#include "../vcd-common-api/vcd-util.h"
#include "../vcd-common-api/vcd-conf/vcd-conf.h"

logined_window *g_logined_window = NULL;

static void Left(void);
static void Right(void);
static void cb_rdp_button(GtkToggleButton *button);
static void grade_dialog(void);
static void fresh_vm_info(void);

GtkWidget *create_connect_status_fix(void);
GtkWidget* create_down_fix(void);
GtkWidget* create_one_vm_button(const vm_info* p);
int create_logined_window(logined_window *logined_window);
void set_button_css_by_vm_info(GtkWidget *btn, const vm_info* p);
gboolean vcd_logined_window_get_guest_ip_callback(gpointer data);

void delete_g_connect_label_and_spinner(void)
{
    if (g_logined_window == NULL)
        return;

    chanage_connect_status(FALSE);
}


static
void Left(void)
{
    struct vcd_conf* tmp_vcd_conf = g_vcd_conf;

    int tmpcount;
    if (PRIVATE_LOGIN == tmp_vcd_conf->login_way)
        tmpcount = g_COUNT;
    else
        tmpcount = g_PUBLIC_COUNT;
    if (g_virtual_list_num <= 0 )
	    return;

    g_virtual_list_num -= 3;//move 3 to left position
    gint t = tmpcount - g_virtual_list_num;
    g_page_list_num = t > 2 ? 3 : t;
    fresh_vm_list();
    
}

static
void Right(void)
{
    struct vcd_conf* tmp_vcd_conf = g_vcd_conf;

    int tmpcount = 0;
    if (PRIVATE_LOGIN == tmp_vcd_conf->login_way)
        tmpcount = g_COUNT;
    else
        tmpcount = g_PUBLIC_COUNT;

    if (g_virtual_list_num >= (tmpcount - 3))
        return;
    
    g_virtual_list_num += 3;

    gint t = tmpcount - g_virtual_list_num;
    g_page_list_num = t > 2 ? 3 : t;

    fresh_vm_list();
}

static
void cb_rdp_button(GtkToggleButton *button)
{

    struct vcd_conf* tmp_vcd_conf = g_vcd_conf;
    if (gtk_toggle_button_get_active(button)) {
        M_DEBUG("set rdp = true");
        tmp_vcd_conf->enable_rdp = 1;
    } else {
        M_DEBUG("set rdp = false");
        tmp_vcd_conf->enable_rdp = 0;
    }
    update_vcd_conf();
}

static
void set_rdp_button(void)
{
    struct vcd_conf* tmp_vcd_conf = g_vcd_conf;
    if (tmp_vcd_conf->enable_rdp)
        gtk_toggle_button_set_active((GtkToggleButton *)g_logined_window->rdp_button, TRUE);
    else
        gtk_toggle_button_set_active((GtkToggleButton *)g_logined_window->rdp_button, FALSE);
}

static void destroy_grade_dialog(gpointer pt)
{
	if(pt == NULL)
		return;
	logined_window* p = (logined_window*)pt;
	gtk_widget_destroy(p->grade_window);
	p->rdp_button = NULL;
	p->grade_window = NULL;	
}

static
void grade_dialog(void)
{
    struct vcd_conf* tmp_vcd_conf = g_vcd_conf;

    GtkWidget *none, *fixed;
    g_logined_window->grade_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_keep_above(GTK_WINDOW(g_logined_window->grade_window), TRUE);
    gtk_window_set_modal((GtkWindow *)g_logined_window->grade_window, TRUE);
    gtk_window_set_position(GTK_WINDOW(g_logined_window->grade_window), GTK_WIN_POS_CENTER_ALWAYS);//居中
    gtk_container_set_border_width(GTK_CONTAINER(g_logined_window->grade_window), 10);
    gtk_window_set_decorated(GTK_WINDOW(g_logined_window->grade_window), FALSE);

    GtkWidget *separ_head  = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
    gtk_widget_set_size_request(separ_head, 300, 1);
    GtkWidget *label_grade = gtk_label_new("高级");
    GtkWidget *btnquit     = gtk_button_new_with_label("X");
    gtk_button_set_relief(GTK_BUTTON(btnquit), GTK_RELIEF_NONE);
    gtk_widget_set_size_request(btnquit, 30, 30);

    none = gtk_label_new(NULL);

    g_logined_window->rdp_button = gtk_check_button_new_with_label("使用RDP协议连接");

    gtk_button_set_relief(GTK_BUTTON(g_logined_window->rdp_button), GTK_RELIEF_NONE);

    fixed = gtk_fixed_new();
    gtk_fixed_put((GtkFixed *)fixed, g_logined_window->rdp_button, 88, 101);
    gtk_fixed_put((GtkFixed *)fixed, none, 88, 151);
    gtk_fixed_put((GtkFixed *)fixed, label_grade, 143, 8);
    gtk_fixed_put((GtkFixed *)fixed, btnquit, 250, 0);
    gtk_fixed_put((GtkFixed *)fixed, separ_head, 0, 43);

    gtk_container_add(GTK_CONTAINER(g_logined_window->grade_window), fixed);
    gtk_widget_show_all(g_logined_window->grade_window);
    g_signal_connect(G_OBJECT(g_logined_window->rdp_button), "toggled", G_CALLBACK(cb_rdp_button), NULL);
    g_signal_connect_swapped(G_OBJECT(btnquit), "clicked", G_CALLBACK(destroy_grade_dialog), g_logined_window);

    set_rdp_button();

    if (tmp_vcd_conf->login_way == PUBLIC_LOGIN)
        gtk_widget_set_sensitive(g_logined_window->rdp_button, FALSE);
    
    set_logined_window_grade_window_css(g_logined_window->grade_window, label_grade, btnquit);
}

static void fresh_vm_info(void)
{
    set_main_vbox_fun();//刷新虚拟机信息而不刷新列表
}

/* 刷新虚拟机列表 */
void fresh_vm_list(void)
{
    if (g_logined_window == NULL || g_logined_window->logined_window_handle == NULL)
        return;

    GtkWidget *frame = g_logined_window->vm_list_frame;
    GtkWidget *org_fix = g_logined_window->vm_list_fix;

    if (org_fix) {
        gtk_widget_destroy(org_fix);
        org_fix = NULL;
    }

    gtk_widget_set_size_request(frame, 301, 140);

    int count;
    struct vcd_conf* tmp_vcd_conf = g_vcd_conf;

    if (PUBLIC_LOGIN == tmp_vcd_conf->login_way)
        count = g_PUBLIC_COUNT;
    else
        count = g_COUNT;

    g_page_list_num = (count >= 3 ? 3 : count);
    GtkWidget *fix = gtk_fixed_new();

    for (int i = 0, j = g_virtual_list_num; j < g_virtual_list_num + g_page_list_num; i++, j++) {
        GtkWidget *f = create_one_vm_button(data + j);

        if (g_page_list_num == 3)
            gtk_fixed_put(GTK_FIXED(fix), f, 0 + 105 * i, 0);

        if (g_page_list_num == 1)
            gtk_fixed_put(GTK_FIXED(fix), f, 105, 0);

        if (g_page_list_num == 2)
            gtk_fixed_put(GTK_FIXED(fix), f, 52 + 105 * i, 0);
    }

    gtk_container_add(GTK_CONTAINER(frame), fix);
    g_logined_window->vm_list_fix = fix;
    gtk_widget_show_all(frame);
}

void exit_logined_window(void)
{
    M_DEBUG("exit_logined_window");
    delete_g_connect_label_and_spinner();

    if (!gtk_toggle_button_get_active((GtkToggleButton *)g_start_window->remember_passwd)) {
        gtk_entry_set_text((GtkEntry *)g_start_window->entry_passwd, "");
    } else {
        if (g_icon_press_state != 0) {
            g_signal_handler_disconnect(G_OBJECT(g_start_window->entry_passwd), g_icon_press_state);
            g_icon_press_state = 0;
        }
    }

    g_page_list_num = 3;
    g_virtual_list_num = 0;

    /*打开定时获取ip的计时器*/
    open_interval_get_ip();

    if (g_logined_window->logined_window_handle) {
        gtk_widget_destroy(GTK_WIDGET(g_logined_window->logined_window_handle));
        g_logined_window->logined_window_handle = NULL;

        //also destroy sub widget
        g_logined_window->main_fix = NULL;
        g_logined_window->vm_list_frame = NULL;
        g_logined_window->vm_list_fix = NULL;
         
        g_logined_window->connect_fix = NULL;
        g_logined_window->connect_label = NULL;
        g_logined_window->connect_spinner = NULL;
    }
    
 

    stop_rdp_thread();

    stop_refresh_thread();

    clean_vm_data();

    vcd_start_window_show();
}

void set_button_css_by_vm_info(GtkWidget *btn, const vm_info* p)
{
    if (g_vcd_conf == NULL)
        return;

    if (PRIVATE_LOGIN == g_vcd_conf->login_way) {

        //M_DEBUG("system_type=%s, status=%s", p->system_type, p->status);

        if (strcmp(p->system_type, "win7") == 0 || strcmp(p->system_type, "wxp") == 0
                || strcmp(p->system_type, "win8") == 0 || strcmp(p->system_type, "win10") == 0
                || strcmp(p->system_type, "other") == 0)
        {
            if (strcmp(p->status, "running") == 0)
                set_logined_window_running_css(btn);
            else
                set_logined_window_stop_css(btn);
        }
        if (strcmp(p->system_type, "l26")  == 0)
        {
            if (strcmp(p->status, "running") == 0)
                set_logined_linux_running_css(btn);
            else
                set_logined_linux_stop_css(btn);
        }
    } else {
        if (strcmp(p->public_ostype, "2") == 0) {
            if (strcmp(p->status, "1") == 0)
                set_logined_public_window_running_css(btn);
            else
                set_logined_public_window_stop_css(btn);
        }
        if (strcmp(p->public_ostype, "1") == 0) {
            if (strcmp(p->status, "1") == 0)
                set_logined_public_linux_running_css(btn);
            else
                set_logined_public_linux_stop_css(btn);
        }
    }
}

GtkWidget* create_one_vm_button(const vm_info* p)
{
    gchar name[25];
    memset(name, 0, sizeof(name));
    const gint max_name_len = 15;
    size_t si_org = strlen(p->name);

    //如果名字太长，最后几位截掉
    if (si_org > max_name_len) {
        memcpy(name, p->name, max_name_len);
        name[14] = '.';
        name[15] = '.';
    } else {
        memcpy(name, p->name, si_org);
    }
    //M_DEBUG(name);

    GtkWidget *fix = gtk_fixed_new();
    GtkWidget *btn = gtk_button_new();
    GtkWidget *label = gtk_label_new(name);

    gtk_widget_set_size_request(btn,   92, 89);
    gtk_widget_set_size_request(label, 95, 15);
    gtk_button_set_relief(GTK_BUTTON(btn), GTK_RELIEF_NONE);//设置无按钮边框
    gtk_fixed_put(GTK_FIXED(fix), btn, 0, 0);
    gtk_fixed_put(GTK_FIXED(fix), label, 0, 120);

    set_button_css_by_vm_info(btn, p);
    g_signal_connect_swapped(G_OBJECT(btn), "clicked", G_CALLBACK(button_enter), (gpointer)p);


    // todo fengfeng
    // get guest ip
    //M_DEBUG("begin vcd_vm_rdp_connect_get_guest_ip_ext net0:%s",p->net0);
    vcd_vm_rdp_connect_get_guest_ip_ext(get_ip_port(),p->node,p->vmid,vcd_logined_window_get_guest_ip_callback,p);

    return fix;
}

void chanage_connect_status(gboolean connectting)
{
    if (g_logined_window == NULL)
        return;

    if (connectting) {
        if(g_logined_window->connect_label)
    	    gtk_label_set_text(GTK_LABEL(g_logined_window->connect_label), "正在连接...");
        if(g_logined_window->connect_spinner)
    	    gtk_spinner_start(GTK_SPINNER(g_logined_window->connect_spinner));
    } else {
        if(g_logined_window->connect_label)
            gtk_label_set_text(GTK_LABEL(g_logined_window->connect_label), "");
        if(g_logined_window->connect_spinner)
            gtk_spinner_stop(GTK_SPINNER(g_logined_window->connect_spinner));
    }

}

GtkWidget *create_connect_status_fix(void)
{
    GtkWidget *connect_label = gtk_label_new("正在连接...");

    GtkWidget *connect_spinner = gtk_spinner_new();
    gtk_spinner_start(GTK_SPINNER(connect_spinner));

    GtkWidget *connect_fix = gtk_fixed_new();
    //  gtk_widget_set_size_request(connect_fix, 300, 50);

    gtk_fixed_put((GtkFixed *)connect_fix, connect_label,   20, 0);
    gtk_fixed_put((GtkFixed *)connect_fix, connect_spinner, 100, 0);

    g_logined_window->connect_label = connect_label;
    g_logined_window->connect_spinner = connect_spinner;
    return connect_fix;
}

GtkWidget* create_down_fix(void)
{
    GtkWidget *btn_grade;//高级
    GtkWidget *btn_fresh;//刷新
    GtkWidget *btn_exit;//登出
    GtkWidget *fix;

    btn_grade = gtk_button_new();
    btn_fresh = gtk_button_new();
    btn_exit  = gtk_button_new();
    fix = gtk_fixed_new();

    gtk_widget_set_size_request(btn_grade, 78, 34);
    gtk_widget_set_size_request(btn_fresh, 78, 34);
    gtk_widget_set_size_request(btn_exit,  78, 34);

    if (g_vcd_conf->enable_grade) {
        gtk_fixed_put((GtkFixed *)fix, btn_grade,  22, 0);
        gtk_fixed_put((GtkFixed *)fix, btn_fresh, 161, 0);
        gtk_fixed_put((GtkFixed *)fix, btn_exit,  282, 0);
    } else {
        gtk_fixed_put((GtkFixed *)fix, btn_fresh, 87, 0);
        gtk_fixed_put((GtkFixed *)fix, btn_exit,  227, 0);
    }   
    gtk_button_set_relief(GTK_BUTTON(btn_grade), GTK_RELIEF_NONE);//设置无按钮边框
    gtk_button_set_relief(GTK_BUTTON(btn_fresh), GTK_RELIEF_NONE);//设置无按钮边框
    gtk_button_set_relief(GTK_BUTTON(btn_exit), GTK_RELIEF_NONE);//设置无按钮边框

    set_logined_window_down_css(btn_exit, btn_grade, btn_fresh);

    gtk_widget_set_sensitive(btn_grade, g_vcd_conf->enable_grade ? TRUE : FALSE);

    g_signal_connect(G_OBJECT(btn_grade), "clicked", G_CALLBACK(grade_dialog), NULL);
    g_signal_connect(G_OBJECT(btn_fresh), "clicked", G_CALLBACK(fresh_vm_info), NULL);
    g_signal_connect(G_OBJECT(btn_exit),  "clicked", G_CALLBACK(exit_logined_window), NULL);

    return fix;
}

int create_logined_window(logined_window *logined_window)
{
    M_DEBUG("create_logined_window");
    GtkWidget* logined_window_handle = NULL;

    logined_window_handle = gtk_window_new(GTK_WINDOW_TOPLEVEL);//按登陆后的窗口
    gtk_window_set_position(GTK_WINDOW(logined_window_handle), GTK_WIN_POS_CENTER_ALWAYS);//居中
    gtk_window_set_decorated(GTK_WINDOW(logined_window_handle), FALSE);//没有菜单栏
    gtk_container_set_border_width(GTK_CONTAINER(logined_window_handle), 45);
    gtk_window_set_resizable(GTK_WINDOW(logined_window_handle), FALSE);//窗口大小不可改变

#ifndef __linux__
    GtkWidget *header = gtk_header_bar_new();
    gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header), TRUE);
    gtk_header_bar_set_title(GTK_HEADER_BAR(header), "");
    gtk_widget_set_size_request(header, -1, 55);
    gtk_window_set_titlebar(GTK_WINDOW(logined_window_handle), header);
    gtk_window_set_decorated(GTK_WINDOW(logined_window_handle), TRUE);
    set_img(header, "headerbar", "loginwindow.png");

    g_signal_connect(G_OBJECT(logined_window_handle), "delete_event", G_CALLBACK(gtk_main_quit), NULL);
#endif

//#ifndef __linux__
//    vcd_common_set_app_icon(logined_window_handle, VCD_PIC_PATH"Vclient.ico");
//#endif

    GtkWidget *main_fix = gtk_fixed_new();

    //move left button
    GtkWidget *btn_left = gtk_button_new();
    gtk_widget_set_size_request(btn_left, 35, 80);
    gtk_button_set_relief(GTK_BUTTON(btn_left),  GTK_RELIEF_NONE);

    //vm list window
    GtkWidget* vm_list_frame = gtk_frame_new ("");
    gtk_widget_set_size_request(vm_list_frame, 293, 91);
    gtk_frame_set_shadow_type(GTK_FRAME(vm_list_frame), GTK_SHADOW_NONE);

    //move right button
    GtkWidget *btn_right = gtk_button_new();
    gtk_widget_set_size_request(btn_right, 35, 80);
    gtk_button_set_relief(GTK_BUTTON(btn_right),  GTK_RELIEF_NONE);

    //connect status
    GtkWidget *connect_status = create_connect_status_fix();
    chanage_connect_status(FALSE);

    //include grade fresh and exit buttion
    GtkWidget *down_fix = create_down_fix();

    gtk_fixed_put(GTK_FIXED(main_fix), btn_left, 0, 30);
    gtk_fixed_put(GTK_FIXED(main_fix), vm_list_frame, 45, 0);
    gtk_fixed_put(GTK_FIXED(main_fix), btn_right, 372, 30);
    gtk_fixed_put(GTK_FIXED(main_fix), connect_status, 130, 172);
    gtk_fixed_put(GTK_FIXED(main_fix), down_fix, 0, 210);

    logined_window->logined_window_handle = logined_window_handle;
    logined_window->main_fix = main_fix;
    logined_window->vm_list_frame = vm_list_frame;

    gtk_container_add(GTK_CONTAINER(logined_window_handle), main_fix);

    set_img(logined_window_handle, "window", "mainwindow.png");

    set_logined_window_left_right_css(btn_left, btn_right);

    g_signal_connect(G_OBJECT(btn_left),  "clicked", G_CALLBACK(Left), NULL);
    g_signal_connect(G_OBJECT(btn_right), "clicked", G_CALLBACK(Right), NULL);

    gtk_widget_show_all(logined_window_handle);

    return 0;
}

void main_logined_window(gboolean is_local_model)//登陆后的背景窗口
{
    M_DEBUG("main_logined_window");
    if (g_logined_window == NULL) {
        g_logined_window = (logined_window *)g_malloc0(sizeof(logined_window));
    }
    
    g_return_if_fail(g_logined_window != NULL);

    g_logined_window->isLocalModel = is_local_model;

    int res = 0;
    res = create_logined_window(g_logined_window);
    if (res != 0) {
        LOG_ERROR("create_logined_window failed");
        G_SAFE_FREE(g_logined_window);
        return;
    }

    //获取虚拟机列表信息
    res = get_vm_list();

    if (res != 0) {
        LOG_ERROR("get vm list failed");
        G_SAFE_FREE(g_logined_window);
        return;
    }

    int refresh_vm_ui_thread_ret = 0;
    refresh_vm_ui_thread_ret = start_refresh_vm_thread();
    if (refresh_vm_ui_thread_ret != 0) {
        LOG_ERROR("start_refresh_vm_thread failed");
        G_SAFE_FREE(g_logined_window);
        return;
    }

    if (gtk_toggle_button_get_active((GtkToggleButton *)g_start_window->auto_login))
        get_record_data_and_connect();
    
    //stop get ip interval
    stop_interval_get_ip();
    //hide login window
    vcd_start_window_hide();
}

void vcd_logined_window_show(){
    M_DEBUG("vcd_logined_window_show");
    g_return_if_fail(g_logined_window != NULL);
    g_return_if_fail(g_logined_window->logined_window_handle != NULL);
    if(!gtk_widget_is_visible(g_logined_window->logined_window_handle)){
        gtk_widget_show_all(g_logined_window->logined_window_handle);
    }
    set_refresh_vm_info_flag(1);
}

void vcd_logined_window_hide(){
    M_DEBUG("vcd_logined_window_hide");
    g_return_if_fail(g_logined_window != NULL);
    g_return_if_fail(g_logined_window->logined_window_handle != NULL);
    if(gtk_widget_is_visible(g_logined_window->logined_window_handle)){
        gtk_widget_hide(g_logined_window->logined_window_handle);
    }
    set_refresh_vm_info_flag(0);
}

gboolean vcd_logined_window_get_guest_ip_callback(gpointer data){
    g_return_val_if_fail(data != NULL, FALSE);
    //M_DEBUG("vcd_logined_window_get_guest_ip_callback");
    network_response *res = (network_response*)data;
    if (res->memory == NULL) {
            M_DEBUG("vcd_logined_window_get_guest_ip_callback get guest ip failed,is ");
        goto end;
    }

    //M_DEBUG("vcd_logined_window_get_guest_ip_callback res->memory:%s",res->memory);

    vm_info* info =  (vm_info*)res->data_priv;
    if(!info) goto end;

    char guest_ip[40] = {0};
    if (json_parser_get_rdp_guest_ip_with_net0(res->memory, guest_ip,info->net0) != 0) {
    }else{
       snprintf(info->guest_ip,sizeof(info->guest_ip),"%s",guest_ip);
    }
    
end:
    network_response_free(&res);
    return FALSE;
}

